/**
 * @fileOverview 列表数据结构
 * @author goodzsq@gmail.com
 * Generator用于优化管理频繁创建与销毁的数据对象，例如游戏中的所有子弹
 * Generator有用一个对象缓冲池，防止对象的频繁创建与销毁
 */

var BaseClass = gg.module('BaseObject');

module.exports = gg.createClass({
    attributes: {
        cacheCount: {
            label: '缓存数量',
            type: 'datatype.Number',
            defaultValue: 10,
            setter: function(v) {
                if (v <= this.objectCount) {
                    return false;
                }
                this.data.length = v;
                var proto = {};
                for (var i = 0; i < v; i++) {
                    if (!this.data[i]) {
                        this.data[i] = _.clone(proto);
                    }
                }
            },
            getter: function() {
                return this.data.length;
            }
        }
    },
    methods: {
        _innerId: 0, //内部对象id追踪
        data: [], //存储缓存数据
        dataMap: {}, //对象id与存储位置的关联
        objectCount: 0, //对象数量
        /**
         * 产生一个新数据对象
         * @param {String} id
         * @param {Object} obj
         * @return {Number}
         */
        addObject: function(id, obj) {
            if (!id) {
                id = this.cid + '_' + this._innerId;
                this._innerId++;
            } else {
                if (this.getObject(id)) {
                    gg.error('id:' + id + 'already exist!');
                }
            }
            if (this.objectCount >= this.data.length) {
                gg.error('datestore overflow');
            }
            var cacheObj = this.data[this.objectCount];
            _.each(obj, function(v, k) {
                cacheObj[k] = v;
            });
            cacheObj.id = id;

            this.dataMap[cacheObj.id] = this.objectCount;
            this.objectCount++;
            this.trigger('onAddObject', this, cacheObj.id, this.objectCount);
            return cacheObj;
        },
        /**
         * 根据id查询对象
         * @param {String} id
         * @return {Object}
         */
        getObject: function(id) {
            return this.getAt(this.dataMap[id]);
        },
        /**
         * 修改数据对象
         * @param {String} id
         * @param {String} key
         * @param {Mixed} value
         */
        setObject: function(id, key, value) {
            var obj = this.getObject(id);
            obj[key] = value;
            this.trigger('onSetObject', this, id, key, value);
        },
        /**
         * 根据数组索引查询对象
         * @param {Number} index
         * @return {Object}
         */
        getAt: function(index) {
            if (index >= 0 && index < this.objectCount) {
                return this.data[index];
            } else {
                return null;
            }
        },
        /**
         * 通过位置销毁一个数据对象
         * @param {Number} index 数组索引
         * @return {Number}
         */
        killAt: function(index) {
            if (index >= 0 && index < this.objectCount) {
                var killTarget = this.data[index];
                var lastObject = this.data[this.objectCount - 1];
                delete this.dataMap[killTarget.id];
                var killTargetId = killTarget.id;
                this.dataMap[lastObject.id] = index;
                _.each(lastObject, function(v, k) {
                    killTarget[k] = v;
                });
                this.objectCount--;
                this.trigger('onKillObject', this, killTargetId, index);
                return this.objectCount;
            } else {
                return false;
            }
        },
        /**
         * 通过id销毁一个数据对象
         * @param {String} id1, id2, id3, ...
         */
        killObject: function(/*...*/) {
            for (var i = 0, max = arguments.length; i < max; i++) {
                var id = arguments[i];
                var index = this.dataMap[id];
                if (index >= 0) {
                    this.killAt(index);
                }
            }
        },
        clear: function() {
            while (this.objectCount > 0) {
                this.killAt(0);
            }
        }
    },
    events: {
        onAddObject: '创建对象',
        onKillObject: '销毁对象',
        onSetObject: '修改对象'
    }
}, BaseClass, []);


/** @fileend */

//unittest
UnitTest.add('struct.List模块测试',
        function() {
            this.test(true, 'ok');
        }
);